import React, { Fragment, useContext, useReducer } from 'react';
import {
  Row,
  Col,
  Menu,
  Icon,
  Dropdown,
  Button,
  Input,
  Checkbox,
  Steps,
  Tooltip,
  Select,
  Form,
  AutoComplete,
  Switch,
} from 'antd';
import classNames from 'classnames';
import { useDeepCompareEffect } from 'ahooks';
import get from 'lodash/get';
import set from 'lodash/set';
import find from 'lodash/find';
import { getUniqueID } from '@/utils/utils';
import ComboGrid from '@/pages/Transformer/components/ComboGrid';
import {
  PRE_PROCESS_TYPE,
  PRE_PROCESS_TRANSFORM,
  PRE_PROCESS_EVALUATION,
  PRE_PROCESS_CUSTOM_TRANSFORMER,
  PRE_PROCESS_JSON_SERIALIZE,
  PRE_PROCESS_JSON_DESERIALIZE,
  PRE_PROCESS_MAPPING,
  PRE_PROCESS_ESCAPE,
  PRE_PROCESS_XML_SERIALIZE,
  PRE_PROCESS_XML_DESERIALIZE,
} from '../settings';
import styles from '../styles.less';
import Mapper from './Mapper';
import CustomHandlerSelector from '@/components/CustomHandlerSelector';
import Context from '@/pages/Transformer/components/SourcePanel/context';
import Space from '@/components/Space';

const { TextArea } = Input;

function judge(value) {
  if (Array.isArray(value) && value.length > 0) {
    return true;
  }

  return false;
}

const initialState = {
  value: [],
};

function reducer(state, action) {
  const { type, payload } = action;

  if (type === 'sync_props') {
    return {
      ...state,
      ...payload,
    };
  }

  if (type === 'toggle') {
    const { checked } = payload;

    return {
      ...state,
      hasPreProcess: checked,
    };
  }

  // if (type === 'change_value') {
  //   const { type, value } = payload;

  //   const newData = [...state.value];

  //   // if (type === PRE_PROCESS_TRANSFORM) {
  //   // } else if (type === PRE_PROCESS_EVALUATION) {
  //   // }

  //   return {
  //     ...state,
  //     value: newData,
  //   };
  // }

  // // 添加后置操作
  // if (type === 'add_pre_process') {
  //   const { type } = payload;

  //   const data = { type, id: getUniqueID('p') };
  //   // 针对`转换`类型的操作
  //   if (type === PRE_PROCESS_TRANSFORM) {
  //     data.transformMap = [{ id: getUniqueID('t') }];
  //   }
  //   return {
  //     ...state,
  //     value: [...state.value, data],
  //   };
  // }
  // // 删除
  // if (type === 'delete_last_one') {
  //   const newData = [...state.value];
  //   newData.pop();

  //   return {
  //     ...state,
  //     value: newData,
  //   };
  // }

  // // 转换 添加一行
  // if (type === 'add_option') {
  //   return {
  //     ...state,
  //     value: state.value.map(k => {
  //       if (k.type === PRE_PROCESS_TRANSFORM) {
  //         k.transformMap = [...k.transformMap, { id: getUniqueID('t') }];
  //       }
  //       return k;
  //     }),
  //   };
  // }
  // // 转换 删除一行
  // if (type === 'delete_option') {
  //   const { id } = payload;
  //   return {
  //     ...state,
  //     value: state.value.map(k => {
  //       if (k.type === PRE_PROCESS_TRANSFORM) {
  //         k.transformMap = k.transformMap.filter(item => item.id !== id);
  //       }
  //       return k;
  //     }),
  //   };
  // }

  throw new Error();
}

function PreProcess({ value, disabled = false, readOnly = false, onChange, filter = () => true }) {
  const [state, dispatch] = useReducer(reducer, initialState);

  const { state: TContext = {} } = useContext(Context);
  const treeData = [get(TContext, 'data')];

  useDeepCompareEffect(() => {
    const data = {};

    // if (Array.isArray(value)) {
    //   data.value =
    //     value.length === 0
    //       ? []
    //       : value.map(k => {
    //           k.id = getUniqueID('id');
    //           return k;
    //         });
    // }

    data.hasPreProcess = judge(value);

    dispatch({ type: 'sync_props', payload: data });
  }, [value]);

  function notify(newValue) {
    if (typeof onChange === 'function') {
      onChange(newValue);
    }
  }

  const list = Array.isArray(value)
    ? value.map(k => {
        if (!k.id) {
          k.id = getUniqueID('id');
        }
        return k;
      })
    : [];

  const menu = (
    <Menu
      onClick={e => {
        const data = { type: e.key, id: getUniqueID('p') };
        // 针对`转换`类型的操作
        if (e.key === PRE_PROCESS_TRANSFORM) {
          data.transformMap = [{ id: getUniqueID('t') }];
        }

        notify([...list, data]);
      }}
    >
      {PRE_PROCESS_TYPE.filter(filter).map(k => (
        <Menu.Item key={k.value}>{k.title}</Menu.Item>
      ))}
    </Menu>
  );

  return (
    <>
      <div className="margin-top margin-bottom">
        <Checkbox
          checked={state.hasPreProcess}
          onChange={e => {
            dispatch({ type: 'toggle', payload: { checked: e.target.checked } });
            notify([]);
          }}
        >
          后置操作
        </Checkbox>
      </div>
      {state.hasPreProcess && (
        <>
          {list.length > 0 && (
            <Steps progressDot direction="vertical" className={styles.process}>
              {list.map((item, itemIndex) => (
                <Steps.Step
                  key={item.id}
                  title={get(find(PRE_PROCESS_TYPE, { value: item.type }), 'title') || '未知类型'}
                  status="finish"
                  description={
                    <>
                      {item.type === PRE_PROCESS_TRANSFORM && (
                        <>
                          {item.transformMap
                            .map(k => {
                              if (!k.id) {
                                k.id = getUniqueID('t');
                                return k;
                              }
                              return k;
                            })
                            .map((k, i) => (
                              <div className={classNames(styles.flex, 'margin-top')} key={k.id}>
                                <div className={styles.control}>
                                  <Input
                                    placeholder="输入"
                                    value={k.input}
                                    addonBefore="输入"
                                    onChange={e => {
                                      set(
                                        list,
                                        `[${itemIndex}].transformMap[${i}].input`,
                                        e.target.value
                                      );
                                      notify(list);
                                    }}
                                  />
                                </div>
                                <div className={styles.control}>
                                  <Input
                                    placeholder="输出"
                                    value={k.output}
                                    addonBefore="输出"
                                    onChange={e => {
                                      set(
                                        list,
                                        `[${itemIndex}].transformMap[${i}].output`,
                                        e.target.value
                                      );
                                      notify(list);
                                    }}
                                  />
                                </div>
                                <div
                                  className={classNames(styles.item, styles.action)}
                                  onClick={() => {
                                    notify(
                                      list.map(k => {
                                        if (k.type === PRE_PROCESS_TRANSFORM) {
                                          k.transformMap = [
                                            ...k.transformMap,
                                            { id: getUniqueID('t') },
                                          ];
                                        }
                                        return k;
                                      })
                                    );
                                  }}
                                >
                                  <Icon type="plus-circle" />
                                </div>
                                <div
                                  className={classNames(styles.item, styles.action)}
                                  onClick={() => {
                                    notify(
                                      list.map(each => {
                                        if (each.type === PRE_PROCESS_TRANSFORM) {
                                          each.transformMap = each.transformMap.filter(
                                            item => item.id !== k.id
                                          );
                                        }
                                        return each;
                                      })
                                    );
                                  }}
                                >
                                  <Icon type="minus-circle" />
                                </div>
                              </div>
                            ))}
                          <div className={classNames(styles.flex, 'margin-top')}>
                            <div className={styles.control}>
                              <Input
                                disabled={item.useOriginalValue}
                                placeholder="默认值"
                                value={item.defaultValue}
                                addonBefore="默认"
                                onChange={e => {
                                  set(list, `[${itemIndex}].defaultValue`, e.target.value);
                                  notify(list);
                                }}
                              />
                            </div>
                            <div style={{ display: 'flex', alignItems: 'center' }}>
                              <Tooltip title="取原字段的值作为默认值">
                                <Checkbox
                                  checked={item.useOriginalValue}
                                  style={{ display: 'inline-block' }}
                                  onChange={e => {
                                    set(list, `[${itemIndex}].defaultValue`, null);
                                    set(list, `[${itemIndex}].useOriginalValue`, e.target.checked);
                                    notify(list);
                                  }}
                                >
                                  原值
                                </Checkbox>
                              </Tooltip>
                            </div>
                          </div>
                        </>
                      )}
                      {item.type === PRE_PROCESS_EVALUATION && (
                        <div className={classNames('margin-top')}>
                          <Input
                            placeholder="#value * 2 + 10"
                            value={item.expression}
                            // style={{ width: 320 }}
                            onChange={e => {
                              set(list, `[${itemIndex}].expression`, e.target.value);
                              notify(list);
                            }}
                          />
                          <div className="margin-top" style={{ color: 'rgba(0, 0, 0, 0.45)' }}>
                            #value表示当前值
                          </div>
                        </div>
                      )}
                      {item.type === PRE_PROCESS_CUSTOM_TRANSFORMER && (
                        <div className={classNames('margin-top')}>
                          <CustomHandlerSelector
                            value={item}
                            onChange={value => {
                              const old = get(list, `[${itemIndex}]`);
                              set(list, `[${itemIndex}]`, { ...old, ...value });
                              notify(list);
                            }}
                            url="/transform/listCustomSingleValueTransformers"
                          />
                        </div>
                      )}
                      {item.type === PRE_PROCESS_JSON_SERIALIZE && (
                        <div className={classNames(styles.flex, 'margin-top')}>
                          将对象或数组压缩成JSON字符串
                        </div>
                      )}
                      {item.type === PRE_PROCESS_JSON_DESERIALIZE && (
                        <div className={classNames(styles.flex, 'margin-top')}>
                          将JSON字符串展开成对象或数组
                        </div>
                      )}
                      {item.type === PRE_PROCESS_XML_SERIALIZE && (
                        <Space className="margin-top" type="vertical">
                          <div>
                            <label className="margin-right">根节点名称: </label>
                            <Input
                              value={item.rootName}
                              onChange={e => {
                                set(list, `[${itemIndex}].rootName`, e.target.value);
                                notify(list);
                              }}
                              style={{ width: 120 }}
                              placeholder="root"
                            />
                          </div>
                          <div>
                            <label className="margin-right">生成头部: </label>
                            <Switch
                              checked={item.includeHead}
                              onChange={checked => {
                                set(list, `[${itemIndex}].includeHead`, checked);
                                notify(list);
                              }}
                            />
                          </div>
                          {item.includeHead && (
                            <div>
                              <label className="margin-right">编码: </label>
                              <AutoComplete
                                value={item.encoding}
                                onChange={value => {
                                  set(list, `[${itemIndex}].encoding`, value);
                                  notify(list);
                                }}
                                dataSource={['UTF-8', 'GBK']}
                                placeholder="UTF-8"
                                style={{ width: 90 }}
                              />
                            </div>
                          )}
                        </Space>
                      )}
                      {item.type === PRE_PROCESS_XML_DESERIALIZE && (
                        <div className={classNames(styles.flex, 'margin-top')}>
                          将XML字符串展开成对象或数组
                        </div>
                      )}
                      {item.type === PRE_PROCESS_MAPPING && (
                        <div className="margin-top">
                          <Mapper
                            treeData={treeData}
                            mode="input"
                            value={item.mapping}
                            onChange={mapping => {
                              set(list, `[${itemIndex}].mapping`, mapping);
                              notify(list);
                            }}
                          />
                        </div>
                      )}
                      {item.type === PRE_PROCESS_ESCAPE && (
                        <div className="margin-top">
                          <label className="margin-right">转义类型: </label>
                          <Select
                            value={item.escapeType}
                            onChange={value => {
                              set(list, `[${itemIndex}].escapeType`, value);
                              notify(list);
                            }}
                            style={{ width: 'auto', minWidth: 90 }}
                            placeholder="请选择"
                          >
                            <Select.Option value="XML_CDATA">CDATA</Select.Option>
                            <Select.Option value="XML_1_0">XML1.0</Select.Option>
                          </Select>
                        </div>
                      )}
                    </>
                  }
                />
              ))}
            </Steps>
          )}

          <Row className="margin-z">
            <Col span={12} style={{ paddingRight: 4 }}>
              <Dropdown overlay={menu} placement="topCenter">
                <Button type="default" block className="text-primary">
                  添加后置操作 <Icon type="down" />
                </Button>
              </Dropdown>
            </Col>
            <Col span={12} style={{ paddingLeft: 4 }}>
              <Button
                type="default"
                block
                disabled={list.length === 0}
                className="text-danger"
                onClick={() => {
                  // dispatch({
                  //   type: 'delete_last_one',
                  // });

                  const newData = [...list];

                  newData.pop();

                  notify(newData);
                }}
              >
                删除最后一条
              </Button>
            </Col>
          </Row>
        </>
      )}
    </>
  );
}

export default PreProcess;
